home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / stayresc.zip / FDIRES.C next >
Text File  |  1985-10-24  |  14KB  |  455 lines

  1.  
  2. /****************************************************************************/
  3. /*                                                                          */
  4. /*     FDIRES.C   Version 1.0  10/23/85                Brian Irvine         */
  5. /*                                                                          */
  6. /*        Released to the Public Domain for use without profit              */
  7. /*                                                                          */
  8. /****************************************************************************/
  9. /*                                                                          */
  10. /* fdires.c - Program to demonstrate use of stayres.c in creating a         */
  11. /*            terminate-and-stay-resident program in DeSmet C.              */
  12. /*                                                                          */
  13. /*            This program demonstrates the techniques used to create a     */
  14. /*            program which will terminate but remain resident as part      */
  15. /*            of DOS.  The program is a sorted directory displayer which    */
  16. /*            will show a sorted and formatted listing of files on the      */
  17. /*            current directory.  It is supplied mainly to demonstrate      */
  18. /*            the techniques involved in creating TSR programs.             */
  19. /*                                                                          */
  20. /*            The program must be linked with the other module in this      */
  21. /*            library using the -s option of bind with a stack allowance    */
  22. /*            of 0x1000 (4096 decimal).  This should be more than           */
  23. /*            adequate for 99% of all applications.                         */
  24. /*                                                                          */
  25. /*             Brian Irvine                                                 */
  26. /*             3379 St Marys Place                                          */
  27. /*             Santa Clara, CA 95051                                        */
  28. /*             [71016,544]                                                  */
  29. /*                                                                          */
  30. /****************************************************************************/
  31.  
  32. #include   "stdio.h"
  33.  
  34. #define    MAX_DIRS        1000
  35.  
  36. #define    DOS_INT         0x21
  37. #define    GET_DRV         0x19
  38.  
  39. #define    FILE_NOT_FOUND  2           /* DOS function error codes */
  40. #define    INVALID_DRIVE   15
  41. #define    NO_MORE_FILES   18
  42.  
  43. struct {
  44.         char   reserved[21];           /* disk transfer area */
  45.         char   attribute;
  46.         int    time;
  47.         int    date;
  48.         long   file_size;
  49.         char   name[13];
  50.         } dta;
  51.  
  52. struct dir_entry{                      /* directory entry */
  53.         char    e_attribute;
  54.         int     e_time;
  55.         int     e_date;
  56.         long    e_file_size;
  57.         char    e_name[13];
  58.         } entry[MAX_DIRS];             /* enough room for 1000 entries */
  59.  
  60. long   free_space;
  61. long   total_space;
  62. int    entries = 0;
  63. int    _rax, _rbx, _rcx, _rdx,     /* variables to hold register values */
  64.               _rsi, _rdi, _rds, _res;
  65. int    row, column;                /* cursor position - must be global */
  66.  
  67. extern char    _carryf;
  68.  
  69. char   label [12];
  70. char   pathname [65];
  71. char   buffer [65];
  72. static char   save_screen[4000];          /* save the screen here */
  73. long   get_free ();
  74.  
  75.  
  76. extern void    stayres();      /* the code to terminate and stay resident */
  77.  
  78.  
  79. /*----- Main ---------------------------------------------------------------*/
  80. /*                                                                          */
  81. /*     In this application all we have to do is call the tsr code.  Other   */
  82. /*     initialization can be performed here before fencing ourselves off.   */
  83. /*                                                                          */
  84. /*--------------------------------------------------------------------------*/
  85.  
  86. main ()
  87. {
  88.  
  89.    stayres ();
  90.  
  91. }
  92.  
  93. /*----- Main program entry point -------------------------------------------*/
  94.  
  95. fdir ()
  96. {
  97.  
  98.    int     n, stat, curr_drv;
  99.    int     mode;
  100.    unsigned    screen_seg;
  101.  
  102.    /* get the video mode */
  103.  
  104.    mode = get_mode ();
  105.  
  106.    /* save the user's screen and cursor position */
  107.  
  108.    find_cursor ();
  109.    if ( mode == 7 )
  110.        screen_seg = 0xB000;
  111.    else
  112.        screen_seg = 0xB800;
  113.    _lmove ( 4000, 0, screen_seg, save_screen, _showds() );
  114.    scr_clr ();
  115.    scr_rowcol (0,0);
  116.  
  117.    entries = 0;
  118.    _setmem (buffer, 65, '\0' );        /* initialize buffers explicitly each */
  119.    _setmem (pathname, 65, '\0' );      /* time through because it changes */
  120.    if ( get_path () == ERR )
  121.        {
  122.        puts ("Invalid drive specifier.\n");
  123.        exit(1);
  124.        }
  125.  
  126. /*     Now construct the path name using current drive                      */
  127.  
  128.    curr_drv = get_curr_drv ();
  129.    buffer[0] = curr_drv + 'A';
  130.    buffer[1] = ':';
  131.    if ( strlen ( pathname ) == 0 )
  132.        buffer[2] = '\0';
  133.    else
  134.        {
  135.        buffer[2] = '\\';
  136.        buffer[3] = '\0';
  137.        }
  138.  
  139.    strcat ( buffer, pathname );
  140.    strcpy ( pathname, buffer );
  141.    n = ( 80 - strlen ( pathname ) - 14 ) / 2;
  142.    strncpy ( buffer, "                                ", n);
  143.    strcat ( buffer, "Directory of " );
  144.    strcat ( buffer, pathname );
  145.    printf ( "%s\n\n", buffer );
  146.    set_dta ();
  147.  
  148. /*     Get the first matching directory entry                               */
  149.  
  150.    if ( get_first () )
  151.        {
  152.        puts ("File not found.\n");
  153.        exit (1);
  154.        }
  155.  
  156. /*     Now collect all the other matching names                             */
  157.  
  158.    while ( ( stat = get_next () ) != NO_MORE_FILES )
  159.        ;
  160.    free_space = get_free ();
  161.    sort_files ();
  162.    print_files ();
  163.  
  164.    /* now put everything back where it was */
  165.  
  166.    puts ("\nPress any key to continue...");
  167.    while ( !scr_csts() )
  168.        ;
  169.  
  170.    _lmove ( 4000, save_screen, _showds(), 0, screen_seg );
  171.    scr_rowcol ( row, column );
  172.  
  173. }
  174.  
  175.  
  176.  
  177. /*----- Get the current drive number ---------------------------------------*/
  178.  
  179. int    get_curr_drv ()
  180. {
  181.  
  182.    return ( _os ( GET_DRV, 0 ) );
  183.  
  184. }
  185.  
  186.  
  187.  
  188. /*----- Get path name of current directory ---------------------------------*/
  189.  
  190. int    get_path ()
  191. {
  192.  
  193.    _rax = 0x4700;
  194.    _rdx = 0;
  195.    _rsi = &pathname[0];
  196.    _rds = _showds();
  197.    _doint ( DOS_INT );
  198.    if ( _carryf )
  199.        return ERR;
  200.  
  201. }
  202.  
  203.  
  204.  
  205. /*----- Give the DTA address to DOS ----------------------------------------*/
  206.  
  207. void   set_dta ()
  208. {
  209.  
  210.    _rax = 0x1A00;
  211.    _rdx = &dta;
  212.    _rds = _showds();
  213.    _doint ( DOS_INT );
  214.  
  215. }
  216.  
  217.  
  218.  
  219. /*----- Get the first matching directory entry -----------------------------*/
  220.  
  221. int    get_first ()
  222. {
  223.  
  224.    strcat ( pathname,"\\*.*" );    /* look for all files */
  225.    _rax = 0x4E00;
  226.    _rdx = &pathname;
  227.    _rcx = 0xFF;                    /* attribute = all */
  228.    _doint ( DOS_INT );
  229.    if ( _carryf )                  /* if there's an error */
  230.        return  ( _rax );           /* send back the code */
  231.    _move ( 22, &dta.attribute, &entry[entries++] );    /* else move data to array */
  232.    return ( 0 );
  233.  
  234. }
  235.  
  236.  
  237.  
  238. /*----- Get next matching directory entry ----------------------------------*/
  239.  
  240. void   get_next ()
  241. {
  242.  
  243.    _rax = 0x4F00;
  244.    _doint ( DOS_INT );
  245.    if ( _carryf )
  246.        return  ( _rax );
  247.    _move ( 22, &dta.attribute, &entry[entries++] );
  248.    return ( 0 );
  249.  
  250. }
  251.  
  252.  
  253. /*----- Get free space left on disk ----------------------------------------*/
  254.  
  255. long   get_free ()
  256. {
  257.  
  258.    _rdx = 0;
  259.    _rax = 0x3600;
  260.    _doint ( DOS_INT );
  261.    total_space = ((long) ( (long)_rax * (long)_rdx * (long)_rcx ));
  262.    return ((long) ( (long)_rax * (long)_rbx * (long)_rcx ));
  263.  
  264. }
  265.  
  266.  
  267.  
  268. /*----- Comparison routine for qsort() -------------------------------------*/
  269.  
  270. int    compare ( first, second )
  271. struct dir_entry *first, *second;
  272. {
  273.  
  274.    return ( strcmp (first -> e_name, second -> e_name ) );
  275.  
  276. }
  277.  
  278.  
  279.  
  280. /*----- Sort the directory entries by name ---------------------------------*/
  281.  
  282. void   sort_files ()
  283. {
  284.  
  285.    qsort ( entry, entries, 22, compare );
  286.  
  287. }
  288.  
  289.  
  290.  
  291. /*----- Get the cursor location --------------------------------------------*/
  292.  
  293.  
  294. void   find_cursor()
  295. {
  296.    _rax = 0x0300;
  297.    _rbx = 0;
  298.    _doint(0x10);
  299.    row = _rdx >> 8;
  300.    column = _rdx & 0x00FF;
  301.  
  302. }
  303.  
  304.  
  305. /*----- Get the current video mode -----------------------------------------*/
  306.  
  307. int    get_mode ()
  308. {
  309.    _rax = 0x0F00;
  310.    _doint ( 0x10 );
  311.    return ( _rax & 0x00FF );
  312.  
  313. }
  314.  
  315.  
  316. /*----- Print the directory entries and free space -------------------------*/
  317. /*                                             this code needs to be redone */
  318.  
  319. void   print_files ()
  320. {
  321.    int i, middle, count, pm, dir, hour;
  322.    struct dir_entry *next;
  323.    char    namebuf[20];
  324.    char    extbuf [4];
  325.    char    *buf, *dirln;
  326.  
  327.    pm = hour = count = 0;
  328.    next = &entry;
  329.    middle = (entries + 1)/2;
  330.    puts ("───────────────────────────────────────┬───────────────────────────────────────\n");
  331.    puts ("Filename Ext   Size     Date     Time  │ Filename Ext   Size     Date     Time \n");
  332.    puts ("───────────────────────────────────────┼───────────────────────────────────────\n");
  333.    for ( count = 0; count < middle; count++ )
  334.        {
  335.        buf = &namebuf;
  336.        dirln = &entry[count].e_name;
  337.        *buf = '\0';
  338.        dir = FALSE;
  339.        if ( entry[count].e_attribute & 0x10 )
  340.            dir = TRUE;
  341.        while ( *dirln && (*dirln != '.'))
  342.            *buf++ = *dirln++;
  343.        *buf = '\0';
  344.        buf = &extbuf;
  345.        *buf = '\0';
  346.        if ( *dirln )
  347.            dirln++;
  348.        strcat( extbuf, dirln );
  349.        hour = ( entry[count].e_time >> 11 ) & 0x001F;
  350.        pm = FALSE;
  351.        if ( hour > 12 )
  352.            {
  353.            hour -= 12;
  354.            pm = TRUE;
  355.            }
  356.        if ( hour == 0 )
  357.            hour = 12;
  358.        if ( dir )
  359.            {
  360.            if ( strlen ( namebuf ) == 0 )
  361.                strcpy ( namebuf, "." );
  362.            else
  363.                ;
  364.            printf ("%-8s %-3s  [Dir]   %2d-%2d-%2d  %2d:%02d%1c │",
  365.                    namebuf,
  366.                    extbuf,
  367.                    (entry[count].e_date >> 5) & 0x000F,
  368.                    (entry[count].e_date & 0x001F),
  369.                    (entry[count].e_date >> 9) + 80,
  370.                    hour,
  371.                    (entry[count].e_time >> 5) & 0x003F,
  372.                    (pm) ? 'p' : 'a');
  373.            }
  374.        else
  375.            printf ("%-8s %-3s  %6D  %2d-%2d-%2d  %2d:%02d%1c │" ,
  376.                    namebuf,
  377.                    extbuf,
  378.                    entry [count].e_file_size,
  379.                    (entry[count].e_date >> 5) & 0x000F,
  380.                    (entry[count].e_date & 0x001F),
  381.                    (entry[count].e_date >> 9) + 80,
  382.                    hour,
  383.                    (entry[count].e_time >> 5) & 0x003F,
  384.                    (pm) ? 'p' : 'a');
  385.        if ( (count + middle) < entries )
  386.            {
  387.            buf = &namebuf;
  388.            dirln = &entry[count + middle].e_name;
  389.            *buf = '\0';
  390.            dir = FALSE;
  391.            if ( entry[count+middle].e_attribute & 0x10 )
  392.                dir = TRUE;
  393.            while ( *dirln && (*dirln != '.'))
  394.                *buf++ = *dirln++;
  395.            *buf = '\0';
  396.            buf = &extbuf;
  397.            *buf = '\0';
  398.            if ( *dirln )
  399.                dirln++;
  400.            strcat( extbuf, dirln );
  401.            hour = ( entry[count + middle].e_time >> 11 ) & 0x001F;
  402.            pm = 0;
  403.            if ( hour > 12 )
  404.                {
  405.                hour -= 12;
  406.                pm = 1;
  407.                }
  408.            if ( hour == 0 )
  409.                hour = 12;
  410.            if ( dir )
  411.                {
  412.                if ( strlen ( namebuf ) == 0 )
  413.                    strcpy ( namebuf, "." );
  414.                else
  415.                    ;
  416.                printf (" %-8s %-3s  [Dir]   %2d-%2d-%2d  %2d:%02d%1c\n",
  417.                        namebuf,
  418.                        extbuf,
  419.                        (entry[count+middle].e_date >> 5) & 0x000F,
  420.                        (entry[count+middle].e_date & 0x001F),
  421.                        (entry[count+middle].e_date >> 9) + 80,
  422.                        hour,
  423.                        (entry[count+middle].e_time >> 5) & 0x003F,
  424.                        (pm) ? 'p' : 'a');
  425.                }
  426.            else
  427.                printf (" %-8s %-3s  %6D  %2d-%2d-%2d  %2d:%02d%1c\n" ,
  428.                        namebuf,
  429.                        extbuf,
  430.                        entry [count+middle].e_file_size,
  431.                        (entry[count+middle].e_date >> 5) & 0x000F,
  432.                        (entry[count+middle].e_date & 0x001F),
  433.                        (entry[count+middle].e_date >> 9) + 80,
  434.                        hour,
  435.                        (entry[count+middle].e_time >> 5) & 0x003F,
  436.                        (pm) ? 'p' : 'a');
  437.            }
  438.        else
  439.            puts ("\n" );
  440.        if ( ( (count + 1) % 17 ) == 0 )
  441.            {
  442.            puts ("─────────────────────────── Press any key to continue ─────────────────────────\n");
  443.            while ( !scr_csts () )
  444.                ;
  445.            }
  446.        }
  447.    puts ("───────────────────────────────────────┼───────────────────────────────────────\n");
  448.    printf (" %3d directory %s                 │", entries, (entries > 1) ? "entries" : "entry  " );
  449.    printf ("  %D bytes free         %3d%% used\n", free_space, 100 * (total_space - free_space) / total_space );
  450.    puts ("───────────────────────────────────────┴───────────────────────────────────────\n");
  451.  
  452. }
  453.  
  454.  
  455.